<div>
    <h3>测试1：吞吐量</h3>
    <div id="show"></div>
</div>
<div>
    <h3>测试2：慢消费者</h3>
    <button id="sendBtn" disabled="true">发送消息</button>
    <span id="show2" style="margin-left: 1em;"></span>
</div>

<script src="../dist/index.js"></script>
<script src="../node_modules/rxjs/dist/bundles/rxjs.umd.js"></script>

<script>
    const { fromEvent, from, of, merge, EMPTY, interval, timer, Observable } = rxjs
    const { map, scan,sample, mergeMap, catchError, repeat, retryWhen, delay, tap, mapTo, take,takeWhile, startWith, switchMap, shareReplay, sampleTime, ignoreElements } = rxjs.operators
    const { getU8Array, fromH5WebSocket, toPeer, getString } = xtp_js

    //客户端
    fromH5WebSocket('ws://localhost:8000/').pipe(
        map(toPeer),
        mergeMap(peer=> peer.onRootRemoteHandler),
        mergeMap(onRootRemoteHandler),
        repeat(),
        retryWhen(errors=>{
            let counter = 0
            return errors.pipe(
                takeWhile(e=> counter++ != 10),
                mergeMap(e=>{
                    console.log("delay retry by " + counter + " second(s)")
                    return timer(counter*1000)
                }),
            )
        }),
        catchError(err=>{
            console.log(err)
            return EMPTY
        }),
    ).subscribe()

    const router = {
        "accHandler": onAccHandler,
        "delayAccHandler": onDelayAccHandler,
    }

    function onRootRemoteHandler(rootRemoteHandler) {
        console.log("onRootRemoteHandler")
        const output = from([
            getU8Array("acc"),
            getU8Array("delayAcc"),
        ]).pipe(
            mergeMap(it=>it),
            // tap(it => console.log(it)),
            tap(it=>rootRemoteHandler.dataSender.next(it)),
            ignoreElements(),
        )
        const input = rootRemoteHandler.onRemoteHandler.pipe(
            mergeMap(remoteHandler=> getString(remoteHandler.info.data).pipe(
                mergeMap(str=>{
                    console.log("remoteHandler.info:", str)
                    const fn = router[str]
                    if (!fn)
                        return EMPTY
                    return fn(remoteHandler)
                }),
            )),
        )
        return merge(input, output).pipe(
            catchError(err=>{
                console.log(err)
                return EMPTY
            }),
        )
    }

    function onAccHandler(remoteHandler) {
        console.log("onAccHandler")
        const divShow = document.getElementById('show')
        const output = merge(
            getU8Array("hi").pipe(
                repeat(remoteHandler.info.channelSize),
            ),
            remoteHandler.onYieldedData,
        ).pipe(
            tap(it=>remoteHandler.dataSender.next(it)),
            ignoreElements()
        )
        const input = remoteHandler.onYieldedData.pipe(
            scan((acc, _) => acc + 1, 0),
            sample(interval(1000)),
            scan((time, count) => {
                //ops
                divShow.innerText = `${count / (time + 1)}/s`
                return time + 1
            }, 0),
            ignoreElements(),
            catchError(e => {
                console.log("onAccHandler err:", e)
                return EMPTY
            }),
        )
        return merge(input, output)
    }

    function onDelayAccHandler(remoteHandler) {
        console.log("onDelayAccHandler")
        const sendBtn = document.getElementById('sendBtn')
        const show2 = document.getElementById('show2')
        const limit = remoteHandler.onAvailable.pipe(
            tap(ok => {
                ok 
                ? sendBtn.removeAttribute("disabled")
                : sendBtn.setAttribute("disabled", true)
            }),
        )
        const output = fromEvent(sendBtn,'click').pipe(
            mergeMap(ev => getU8Array("hi")),
            tap(it=>remoteHandler.dataSender.next(it)),
            ignoreElements()
        )
        const input = remoteHandler.onYieldedData.pipe(
            mergeMap(data => getString(data)),
            tap(str => show2.innerText = str),
            ignoreElements(),
            catchError(e => {
                console.log("onDelayAccHandler err:", e)
                return EMPTY
            }),
        )
        return merge(input, output, limit)
    }
</script>